package tests;

import java.util.ArrayList;
import java.util.Random;

import models.Phrase;
import models.Score;
import models.Track;

import org.jfugue.Pattern;
import org.jfugue.Rhythm;

public class MockGenerator {

	
	//divide by the powers of two to get note lengths
		//Octave values 1-10 (1 = Lowest Octave, 10 = Highest Octave)
		//12 semi-tones - Octave * semitone = Numeric values for notes at the begining of octaves.
		//Default Time signature is 4/4 time
		Random random = new Random();
		final int SEMI_TONE_COUNT = 12;
		
		private int octave;
		
		public int[] powersOfTwo = new int[]{2, 4, 8, 16};
		public int[] harmonicValues = new int[]{3, 5, 8};
		public int[] naturalNoteValues = new int[]{0, 2, 4, 5, 7, 9, 11};
		ArrayList<Integer> values = new ArrayList<Integer>();
		ArrayList<Double> lengths = new ArrayList<Double>();
		
		private StringBuilder generatedString;
		
		public Pattern generateNewTrack(Track newTrackModel)
		{
			generatedString = new StringBuilder();
			values = new ArrayList<Integer>();
			lengths = new ArrayList<Double>();
			generatedString.append("T" + newTrackModel.tempo + " " + newTrackModel.keySignature + " ");
			
			for(int i=0; i < newTrackModel.instruments.length; i++)
			{
				Score score = new Score();
				if(newTrackModel.instruments[i].equals("Drums"))
				{
					if(i==0)
					{
						generatedString = new StringBuilder();
						generatedString.append("T" + newTrackModel.tempo + " ");
					}
					generateRhythm(newTrackModel);
				}
				else
				{
					generatedString.append("V" + i + " I[" + newTrackModel.instruments[i] + "] ");
					
					score = generateScore(newTrackModel, i);
				}
				getMusicString(score);
			}
			return new Pattern(generatedString.toString());
		}
		
		private Score generateScore(Track newTrackModel, int instrument)
		{
			Score score = new Score();
			for(int j=0; j < newTrackModel.phraseAmount; j++)
			{
				Phrase phrase = new Phrase();
				
				octave = random.nextInt(4) + 3;
				MockMeasure measure = new MockMeasure();
				measure.generateMeasures(newTrackModel, instrument, octave, lengths, values);
				phrase.addMeasure(measure);
				score.addPhrase(phrase);
			}
			return score;
		}
		
		private void getMusicString(Score score) 
		{
			for(Phrase p : score.phrases)
			{
				for(MockMeasure m : p.mockMeasures)
				{
					generatedString.append(m.content);
				}
			}
		}

		private void generateRhythm(Track newTrackModel) {
			
			for(int j=0; j < newTrackModel.phraseAmount; j++)
			{
				octave = random.nextInt(4) + 3;
				for(int k=0; k < newTrackModel.measuresPerPhrase; k++)
				{
					Rhythm rhythm = new Rhythm();
					rhythm.setLayer(1, "O..oO...O..oOO..");
					rhythm.setLayer(2, "..*...*...*...*.");
					rhythm.setLayer(3, "^.^.^.^.^.^.^.^.");
					rhythm.setLayer(4, "...............!");
					// Step 2. Identify instruments to use in the beat
					// (In this example, each MusicString should have a
					// total duration of an eighth note)
					rhythm.addSubstitution('O', "[BASS_DRUM]i");
					rhythm.addSubstitution('o', "Rs [BASS_DRUM]s");
					rhythm.addSubstitution('*', "[ACOUSTIC_SNARE]i");
					rhythm.addSubstitution('^',"[PEDAL_HI_HAT]t Rt [CLOSED_HI_HAT]t Rt");
					rhythm.addSubstitution('.', "Ri");
					generatedString.append(rhythm.getPattern().toString());	
				}
			}
		}
}
